package com.my.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.my.code.CodingService;
import com.my.entity.TysbdmDO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 地址统一识别代码表-接口调用 前端控制器
 * </p>
 *
 * @author generator
 * @since 2024-07-22
 */
@Slf4j
@RestController
@RequestMapping("coding")
public class TysbdmController {

    @Resource
    CodingService codingService;

    @GetMapping("start")
    @Operation(summary = "开始赋码,异步处理。", description = "flag=false,代表首次赋码，取表中状态为0的数据；flag=true,代表再次赋码，取表中状态为2的数据")
    public String start(@RequestParam(value = "size", required = false, defaultValue = "500") @Parameter(description = "默认的批处理大小") int size,
                        @RequestParam(value = "flag", required = false, defaultValue = "false") @Parameter(description = "是否是处理赋码失败的数据，默认否") boolean flag) {
        TysbdmDO tysbdm = TysbdmDO.builder().build();
        LambdaQueryWrapper<TysbdmDO> query = Wrappers.<TysbdmDO>lambdaQuery().eq(TysbdmDO::getStatus, flag ? 2 : 0);
        long count = tysbdm.selectCount(query);
        long batch = count / size + 1;
        new Thread(() -> handle(tysbdm, batch, size, query, flag)).start();
        return String.format("赋码请求已经提交，后台正在处理，请勿重复操作。总共需要处理的数据量: %s条, 总共分为: %s个批次处理。", count, batch);
    }

    public void handle(TysbdmDO tysbdm, long batch, int size, LambdaQueryWrapper<TysbdmDO> query, boolean flag) {
        long start = System.currentTimeMillis();
        int success = 0;
        int fail = 0;
        for (int i = 0; i < batch; i++) {
            query.last(" limit " + i + "," + size);
            List<TysbdmDO> batchList = tysbdm.selectList(query);
            log.info("开始处理第{}批次数据，共计{}数据", i, batchList.size());
            for (int j = 0; j < batchList.size(); j++) {
                log.info("开始处理第{}批次数据,第{}条数据", i, j);
                TysbdmDO tysbdmDO = batchList.get(j);
                CodingService.CodeData code;
                try {
                    if (flag) { // 注销并重启
                        if(StringUtils.isEmpty(tysbdmDO.getCode())){
                            throw new RuntimeException("code值为空，修正数据后设置为待赋码状态");
                        }
                        codingService.cancel(tysbdmDO.getCode());
                        codingService.enable(tysbdmDO.getCode());
                    }
                    code = codingService.register(tysbdmDO);
                } catch (Exception e) {
                    log.error(e.toString());
                    tysbdm.update(Wrappers.<TysbdmDO>lambdaUpdate()
                            .eq(TysbdmDO::getId, tysbdmDO.getId())
                            .set(TysbdmDO::getMessage, e.getMessage())
                            .set(TysbdmDO::getRequestTime, LocalDateTime.now())
                            .set(TysbdmDO::getStatus, 2));
                    fail++;
                    continue;
                }
                tysbdm.update(Wrappers.<TysbdmDO>lambdaUpdate()
                        .eq(TysbdmDO::getId, tysbdmDO.getId())
                        .set(TysbdmDO::getBeidou2d, code.getBeiDou2d())
                        .set(TysbdmDO::getBeidou3d, code.getBeiDou3d())
                        .set(TysbdmDO::getMessage, null)
                        .set(TysbdmDO::getCode, code.getCode())
                        .set(TysbdmDO::getRequestTime, LocalDateTime.now())
                        .set(TysbdmDO::getStatus, 1));
                success++;
                log.info("第{}批次数据,第{}条数据,处理完毕", i, j);
            }
            log.info("第{}批次数据，共计{}数据，处理完毕。", i, batchList.size());
        }
        long end = System.currentTimeMillis();
        String msg = String.format("总共处理: %s个批次,共计耗时%s秒。处理成功%s条，处理失败%s条数据。", batch, (end - start) / 1000, success, fail);
        log.info(msg);
    }
}
